#include <iostream>
#include <functional>
#include <math.h>

using std::cout;
using std::endl;
using std::bind;
using std::function;

class Figure{
private:
    using DisplayCallback = function<void()>;   // 定义无参无返回值的回调类型
    using AreaCallback = function<double()>;    // 定义无参返回double的回调类型

    DisplayCallback _displayCallback;           // 存储显示回调函数对象
    AreaCallback _areaCallback;                 // 存储面积计算回调函数对象

public:
    // 注册显示回调，cb必须是右值（通常为临时Lambda）
    void setDisplayCallback(DisplayCallback &&cb){  
        _displayCallback = std::move(cb);       // 将右值引用绑定到临时对象（减少拷贝）
    }

    void setAreaCallback(AreaCallback &&cb){
        _areaCallback = std::move(cb);
    }
    
    // 执行显示回调，安全检查空指针
    void handleDisplayCallback() const{     
        if(_displayCallback){                   // 检查回调是否有效
            _displayCallback();                 // lambda调用绑定的函数成员，例如rectangle.display()
        }
    }

    double handleAreaCallback() const{
        if(_areaCallback){
            return _areaCallback();
        }else{
            return 0.0;
        }
    }
};

class Rectangle{
private:
    double _len;
    double _width;
public:
    Rectangle(double len = 0, double width = 0)
        :_len(len), _width(width){ cout << "Rectangle(double = 0, double = 0)" << endl; }

    // 显示函数，参数x未使用（可考虑移除）
    void display(int x) const{      // 具体图形类的显示方法
        cout << "Rectangle"; 
    }
    
    double area() const{ 
        return _len * _width; 
    }
    ~Rectangle() { 
        cout << "~Rectangle()" << endl; 
    }

};

class Circle{
private:
    double _radius;
public:
    explicit Circle(double radius = 0)
        :_radius(radius){ cout << "Circle(double = 0)" << endl; }

    void print() const{         // 2：派生类函数
        cout << "Circle"; 
    }

    double printArea() const{ 
        return 3.14 * _radius; 
    }

    ~Circle(){
        cout << "~Circle()" << endl;
    }
};

class Triangle{
private:
    double _a;
    double _b;
    double _c;
public:
    Triangle(double a = 0, double b = 0, double c = 0)
        : _a(a), _b(b), _c(c){
            cout << "Triangle(double = 0, double = 0, double = 0)" << endl;
        }

    void show() const{
        cout << "Triangle";
    }

    double showArea() const{
        double tmp = (_a + _b + _c) / 2;
        return sqrt(tmp * (tmp - _a) * (tmp - _b) * (tmp - _c));
    }

    ~Triangle(){
        cout << "~Triangle" << endl;
    }
};

void func(const Figure &ref){
    ref.handleAreaCallback();
    cout << "s 的面积 : " << ref.handleAreaCallback() << endl;
}

void test(){
    // 注意，局部对象生命周期必须长于Figure对象
    Rectangle rec(10, 20);
    Circle cir(10);
    Triangle tri(3, 4, 5);

    Figure fig;     // 类Figure的函数对象

    // 绑定成员函数，100作为display的第一个参数
    // bind参数说明：成员函数指针，对象地址，成员函数第一个参数值
    fig.setDisplayCallback(bind(&Rectangle::display, &rec, 100));
    fig.setAreaCallback(bind(&Rectangle::area, &rec));
    func(fig);      // 执行函数

    fig.setDisplayCallback(bind(&Circle::print, &cir));
    fig.setAreaCallback(bind(&Circle::printArea, &cir));
    func(fig);

    fig.setDisplayCallback(bind(&Triangle::show, &tri));
    fig.setAreaCallback(bind(&Triangle::showArea, &tri));
    func(fig);
}

int main(){

    return 0;
}

